home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / netBoot / RCS / inet.c,v < prev    next >
Encoding:
Text File  |  1990-10-10  |  19.3 KB  |  837 lines

  1. head     1.2;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.2
  10. date     90.10.10.15.16.16;  author mendel;  state Exp;
  11. branches ;
  12. next     1.1;
  13.  
  14. 1.1
  15. date     89.06.20.10.32.00;  author mendel;  state Exp;
  16. branches ;
  17. next     ;
  18.  
  19.  
  20. desc
  21. @@
  22.  
  23.  
  24. 1.2
  25. log
  26. @*** empty log message ***
  27. @
  28. text
  29. @#ifndef lint
  30. static    char sccsid[] = "@@(#)inet.c    1.12 88/02/08    Copyr 1986 Sun Micro";
  31. #endif
  32.  
  33. /*
  34.  * Copyright (c) 1986 by Sun Microsystems, Inc.
  35.  */
  36.  
  37. /*
  38.  * Standalone IP send and receive - specific to Ethernet
  39.  * Includes ARP and Reverse ARP
  40.  */
  41. #include "machparam.h"
  42. #include "boot.h"
  43. #include "saio.h"
  44. #include "socket.h"
  45. #include "if.h"
  46. #include "if_arp.h"
  47. #include "in.h"
  48. #include "if_ether.h"
  49. #include "in_systm.h"
  50. #include "ip.h"
  51. #include "sainet.h"
  52. #include "sunromvec.h"
  53. #include "idprom.h"
  54.  
  55. #define millitime() (*romp->v_nmiclock)
  56.  
  57. struct ether_addr etherbroadcastaddr = { 
  58.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  59. };
  60.  
  61. struct arp_packet {
  62.     struct ether_header    arp_eh;
  63.     struct ether_arp    arp_ea;
  64. #define    used_size (sizeof (struct ether_header)+sizeof(struct ether_arp))
  65.     char    filler[ETHERMIN - sizeof(struct ether_arp)];
  66. };
  67.  
  68. #define WAITCNT    2    /* 4 seconds before bitching about arp/revarp */
  69.  
  70. /*
  71.  * Fetch our Ethernet address from the ID prom
  72.  */
  73. myetheraddr(ea)
  74.     struct ether_addr *ea;
  75. {
  76.     struct idprom id;
  77.  
  78.     if (idprom(IDFORM_1, &id) != IDFORM_1) {
  79.         printf("ERROR: missing or invalid ID prom\n");
  80.         return;
  81.     }
  82.     *ea = *(struct ether_addr *)id.id_ether;
  83. }
  84.  
  85. /*
  86.  * Initialize IP state
  87.  * Find out our Ethernet address and call Reverse ARP
  88.  * to find out our Internet address
  89.  * Set the ARP cache to the broadcast host
  90.  */
  91. inet_init(sip, sain, tmpbuf)
  92.     register struct saioreq *sip;
  93.     register struct sainet *sain;
  94.     char *tmpbuf;
  95. {
  96.     myetheraddr(&sain->sain_myether);
  97.     bzero((caddr_t)&sain->sain_myaddr, sizeof(struct in_addr));
  98.     bzero((caddr_t)&sain->sain_hisaddr, sizeof(struct in_addr));
  99.     sain->sain_hisether = etherbroadcastaddr;
  100.     revarp(sip, sain, tmpbuf);
  101. }
  102.  
  103.  
  104. /*
  105.  * Output an IP packet
  106.  * Cause ARP to be invoked if necessary
  107.  */
  108. ip_output(sip, buf, len, sain, tmpbuf)
  109.     register struct saioreq *sip;
  110.     caddr_t buf, tmpbuf;
  111.     short len;
  112.     register struct sainet *sain;
  113. {
  114.     register struct ether_header *eh;
  115.     register struct ip *ip;
  116.  
  117.     eh = (struct ether_header *)buf;
  118.     ip = (struct ip *)(buf + sizeof(struct ether_header));
  119.     if (bcmp((caddr_t)&ip->ip_dst,
  120.         (caddr_t)&sain->sain_hisaddr,
  121.         sizeof(struct in_addr)) != 0) {
  122.             bcopy((caddr_t)&ip->ip_dst,
  123.                 (caddr_t)&sain->sain_hisaddr,
  124.                 sizeof (struct in_addr));
  125.             arp(sip, sain, tmpbuf);
  126.     }
  127.     eh->ether_type = ETHERTYPE_IP;
  128.     eh->ether_shost = sain->sain_myether;
  129.     eh->ether_dhost = sain->sain_hisether;
  130.     /* checksum the packet */
  131.     ip->ip_sum = 0;
  132.     ip->ip_sum = ipcksum((caddr_t)ip, sizeof (struct ip));
  133.     if (len < ETHERMIN + sizeof(struct ether_header)) {
  134.         len = ETHERMIN+sizeof(struct ether_header);
  135.     }
  136.     return (*sip->si_sif->sif_xmit)(sip->si_devdata, buf, len);
  137. }
  138.  
  139. /*
  140.  * Check incoming packets for IP packets
  141.  * addressed to us. Also, respond to ARP packets
  142.  * that wish to know about us.
  143.  * Returns a length for any IP packet addressed to us, 0 otherwise.
  144.  */
  145. ip_input(sip, buf, sain)
  146.     register struct saioreq *sip;
  147.     caddr_t buf;
  148.     register struct sainet *sain;
  149. {
  150.     register short len;
  151.     register struct ether_header *eh;
  152.     register struct ip *ip;
  153.     register struct ether_arp *ea;
  154.  
  155.     len = (*sip->si_sif->sif_poll)(sip->si_devdata, buf);
  156.     eh = (struct ether_header *)buf;
  157.     if (eh->ether_type == ETHERTYPE_IP &&
  158.         len >= sizeof(struct ether_header)+sizeof(struct ip)) {
  159.         ip = (struct ip *)(buf + sizeof(struct ether_header));
  160. #ifdef NOREVARP
  161.         if ((sain->sain_hisaddr.s_addr & 0xFF000000) == 0 &&
  162.             bcmp((caddr_t)ðerbroadcastaddr,
  163.             (caddr_t)&eh->ether_dhost,
  164.             sizeof(struct ether_addr)) != 0 &&
  165.             (in_broadaddr(sain->sain_hisaddr) ||
  166.             in_lnaof(ip->ip_src) == in_lnaof(sain->sain_hisaddr))) {
  167.             sain->sain_myaddr = ip->ip_dst;
  168.             sain->sain_hisaddr = ip->ip_src;
  169.             sain->sain_hisether = eh->ether_shost;
  170.         }
  171. #endif
  172.         if (bcmp((caddr_t)&ip->ip_dst,
  173.             (caddr_t)&sain->sain_myaddr,
  174.             sizeof(struct in_addr)) != 0)
  175.             return (0);
  176.         return (len);
  177.     }
  178.     if (eh->ether_type == ETHERTYPE_ARP &&
  179.         len >= sizeof(struct ether_header) + sizeof(struct ether_arp)) {
  180.         ea = (struct ether_arp *)(buf + sizeof(struct ether_header));
  181.         if (ea->arp_pro != ETHERTYPE_IP)
  182.             return (0);
  183.         if (bcmp((caddr_t)ea->arp_spa,
  184.             (caddr_t)&sain->sain_hisaddr,
  185.             sizeof(struct in_addr)) == 0)
  186.             sain->sain_hisether = ea->arp_sha;
  187.         if (ea->arp_op == ARPOP_REQUEST &&
  188.             (bcmp((caddr_t)ea->arp_tpa,
  189.               (caddr_t)&sain->sain_myaddr,
  190.               sizeof(struct in_addr)) == 0)) {
  191.             ea->arp_op = ARPOP_REPLY;
  192.             eh->ether_dhost = ea->arp_sha;
  193.             eh->ether_shost = sain->sain_myether;
  194.             ea->arp_tha = ea->arp_sha;
  195.             bcopy((caddr_t)ea->arp_spa,
  196.                 (caddr_t)ea->arp_tpa,
  197.                 sizeof(ea->arp_tpa));
  198.             ea->arp_sha = sain->sain_myether;
  199.             bcopy((caddr_t)&sain->sain_myaddr,
  200.                 (caddr_t)ea->arp_spa,
  201.                 sizeof(ea->arp_spa));
  202.             (*sip->si_sif->sif_xmit)(sip->si_devdata, buf, 
  203.                         sizeof(struct arp_packet));
  204.         }
  205.         return (0);
  206.     }
  207.     return (0);
  208. }
  209.  
  210. /*
  211.  * arp
  212.  * Broadcasts to determine Ethernet address given IP address
  213.  * See RFC 826
  214.  */
  215. arp(sip, sain, tmpbuf)
  216.     register struct saioreq *sip;
  217.     register struct sainet *sain;
  218.     char *tmpbuf;
  219. {
  220.     struct arp_packet out;
  221.  
  222.     if (in_broadaddr(sain->sain_hisaddr)
  223. #ifdef NOREVARP
  224.         || (sain->sain_hisaddr.s_addr & 0xFF000000) == 0
  225. #endif
  226.         ) {
  227.         sain->sain_hisether = etherbroadcastaddr;
  228.         return;
  229.     }
  230.     out.arp_eh.ether_type = ETHERTYPE_ARP;
  231.     out.arp_ea.arp_op = ARPOP_REQUEST;
  232.     out.arp_ea.arp_tha = etherbroadcastaddr;    /* what we want */
  233.     bcopy((caddr_t)&sain->sain_hisaddr,
  234.         (caddr_t)out.arp_ea.arp_tpa,
  235.         sizeof(sain->sain_hisaddr));
  236.     comarp(sip, sain, &out, tmpbuf);
  237. }
  238.  
  239. /*
  240.  * Reverse ARP client side
  241.  * Determine our Internet address given our Ethernet address
  242.  * See RFC 903
  243.  */
  244. revarp(sip, sain, tmpbuf)
  245.     register struct saioreq *sip;
  246.     register struct sainet *sain;
  247.     char *tmpbuf;
  248. {
  249.     struct arp_packet out;
  250.  
  251. #ifdef NOREVARP
  252.     bzero((caddr_t)&sain->sain_myaddr, sizeof(struct in_addr));
  253.     bcopy((caddr_t)&sain->sain_myether.ether_addr_octet[3],
  254.         (caddr_t)(&sain->sain_myaddr)+1, 3);
  255. #else
  256.     out.arp_eh.ether_type = ETHERTYPE_REVARP;
  257.     out.arp_ea.arp_op = REVARP_REQUEST;
  258.     out.arp_ea.arp_tha = sain->sain_myether;
  259.     /* What we want to find out... */
  260.     bzero(out.arp_ea.arp_tpa, sizeof(struct in_addr));
  261.     comarp(sip, sain, &out, tmpbuf);
  262. #endif
  263. }
  264.  
  265. /*
  266.  * Common ARP code 
  267.  * Broadcast the packet and wait for the right response.
  268.  * Fills in *sain with the results
  269.  */
  270. comarp(sip, sain, out, tmpbuf)
  271.     register struct saioreq *sip;
  272.     register struct sainet *sain;
  273.     register struct arp_packet *out;
  274.     char *tmpbuf;
  275. {
  276.     register struct arp_packet *in = (struct arp_packet *)tmpbuf;
  277.     register int e, count, time, feedback,len, delay = 2;
  278.     char    *ind = "-\|/";
  279.     struct in_addr tmp_ia;
  280.  
  281.     out->arp_eh.ether_dhost = etherbroadcastaddr;
  282.     out->arp_eh.ether_shost = sain->sain_myether;
  283.     out->arp_ea.arp_hrd =  ARPHRD_ETHER;
  284.     out->arp_ea.arp_pro = ETHERTYPE_IP;
  285.     out->arp_ea.arp_hln = sizeof(struct ether_addr);
  286.     out->arp_ea.arp_pln = sizeof(struct in_addr);
  287.     out->arp_ea.arp_sha = sain->sain_myether;
  288.     bcopy((caddr_t)&sain->sain_myaddr,
  289.         (caddr_t)out->arp_ea.arp_spa, 
  290.         sizeof(out->arp_ea.arp_spa));
  291.     feedback = 0;
  292.  
  293.     for (count=0; ; count++) {
  294.         if (count == WAITCNT) {
  295.             if (out->arp_ea.arp_op == ARPOP_REQUEST) {
  296.                 printf("\nRequesting Ethernet address for ");
  297.                 bcopy((caddr_t)out->arp_ea.arp_tpa,
  298.                     (caddr_t)&tmp_ia, sizeof(tmp_ia));
  299.                 inet_print(tmp_ia);
  300.             } else {
  301.                 printf("\nRequesting Internet address for ");
  302.                 ether_print(&out->arp_ea.arp_tha);
  303.             }
  304.         }
  305.         e = (*sip->si_sif->sif_xmit)(sip->si_devdata, (caddr_t)out,
  306.             sizeof *out);
  307.         if (e)
  308.             printf("X\b");
  309.         else
  310.             printf("%c\b", ind[feedback++ % 4]); /* Show activity */
  311.  
  312.         time = millitime() + (delay * 1000);    /* broadcast delay */
  313.         while (millitime() <= time) {
  314.             len = (*sip->si_sif->sif_poll)(sip->si_devdata, tmpbuf);
  315.             if (len < used_size)
  316.                 continue;
  317.             if (in->arp_ea.arp_pro != ETHERTYPE_IP)
  318.                 continue;
  319.             if (out->arp_ea.arp_op == ARPOP_REQUEST) {
  320.                 if (in->arp_eh.ether_type != ETHERTYPE_ARP)
  321.                     continue;
  322.                 if (in->arp_ea.arp_op != ARPOP_REPLY)
  323.                     continue;
  324.                 if (bcmp((caddr_t)in->arp_ea.arp_spa,
  325.                     (caddr_t)out->arp_ea.arp_tpa,
  326.                      sizeof(struct in_addr)) != 0)
  327.                     continue;
  328.                 if (count >= WAITCNT) {
  329.                     printf("Found at ");
  330.                     ether_print(&in->arp_ea.arp_sha);
  331.                 }
  332.                 sain->sain_hisether = in->arp_ea.arp_sha;
  333.                 return;
  334.             } else {        /* Reverse ARP */
  335.                 if (in->arp_eh.ether_type !=ETHERTYPE_REVARP)
  336.                     continue;
  337.                 if (in->arp_ea.arp_op != REVARP_REPLY)
  338.                     continue;
  339.                 if (bcmp((caddr_t)&in->arp_ea.arp_tha,
  340.                     (caddr_t)&out->arp_ea.arp_tha, 
  341.                     sizeof (struct ether_addr)) != 0)
  342.                     continue;
  343.  
  344.                 if (count >= WAITCNT) {
  345.                     printf("Internet address is ");
  346.                     bcopy((caddr_t)in->arp_ea.arp_tpa,
  347.                         (caddr_t)&tmp_ia, sizeof(tmp_ia));
  348.                     inet_print(tmp_ia);
  349.                 }
  350.                 bcopy((caddr_t)in->arp_ea.arp_tpa, 
  351.                     (caddr_t)&sain->sain_myaddr,
  352.                     sizeof(sain->sain_myaddr));
  353.                 /*
  354.                  * short circuit first ARP
  355.                  */
  356.                 bcopy((caddr_t)in->arp_ea.arp_spa, 
  357.                     (caddr_t)&sain->sain_hisaddr,
  358.                     sizeof(sain->sain_hisaddr));
  359.                 sain->sain_hisether = in->arp_ea.arp_sha;
  360.                 return;
  361.             }
  362.         }
  363.  
  364.         delay = delay * 2;    /* Double the request delay */
  365.         if (delay > 64)        /* maximum delay is 64 seconds */
  366.             delay = 64;
  367.  
  368.         (*sip->si_sif->sif_reset)(sip->si_devdata);
  369.     }
  370.     /* NOTREACHED */
  371. }
  372.  
  373. /*
  374.  * Return the host portion of an internet address.
  375.  */
  376. in_lnaof(in)
  377.     struct in_addr in;
  378. {
  379.     register u_long i = ntohl(in.s_addr);
  380.  
  381.     if (IN_CLASSA(i))
  382.         return ((i)&IN_CLASSA_HOST);
  383.     else if (IN_CLASSB(i))
  384.         return ((i)&IN_CLASSB_HOST);
  385.     else
  386.         return ((i)&IN_CLASSC_HOST);
  387. }
  388.  
  389. /*
  390.  * Test for broadcast IP address
  391.  */
  392. in_broadaddr(in)
  393.     struct in_addr in;
  394. {
  395.     register u_long i = ntohl(in.s_addr);
  396.  
  397.     if (IN_CLASSA(i)) {
  398.         i &= IN_CLASSA_HOST;
  399.         return (i == 0 || i == 0xFFFFFF);
  400.     } else if (IN_CLASSB(i)) {
  401.         i &= IN_CLASSB_HOST;
  402.         return (i == 0 || i == 0xFFFF);
  403.     } else if (IN_CLASSC(i)) {
  404.         i &= IN_CLASSC_HOST;
  405.         return (i == 0 || i == 0xFF);
  406.     } else
  407.         return (0);
  408.     /*NOTREACHED*/
  409. }
  410.  
  411. /*
  412.  * Compute one's complement checksum
  413.  * for IP packet headers 
  414.  */
  415. ipcksum(cp, count)
  416.     caddr_t    cp;
  417.     register unsigned short    count;
  418. {
  419.     register unsigned short    *sp = (unsigned short *)cp;
  420.     register unsigned long    sum = 0;
  421.     register unsigned long    oneword = 0x00010000;
  422.  
  423.     count >>= 1;
  424.     while (count--) {
  425.         sum += *sp++;
  426.         if (sum >= oneword) {        /* Wrap carries into low bit */
  427.             sum -= oneword;
  428.             sum++;
  429.         }
  430.     }
  431.     return (~sum);
  432. }
  433.  
  434. inet_print(s)
  435.     struct in_addr s;
  436. {
  437.     printf("%d.%d.%d.%d\n",
  438.         (s.s_addr >> 24) & 0xff,
  439.         (s.s_addr >> 16) & 0xff,
  440.         (s.s_addr >>  8) & 0xff,
  441.         s.s_addr & 0xff);
  442. }
  443.  
  444. ether_print(ea)
  445.     struct ether_addr *ea;
  446. {
  447.     register u_char *p = &ea->ether_addr_octet[0];
  448.  
  449.     printf("%x:%x:%x:%x:%x:%x\n", p[0], p[1], p[2], p[3], p[4], p[5]);
  450. }
  451. @
  452.  
  453.  
  454. 1.1
  455. log
  456. @Initial revision
  457. @
  458. text
  459. @d1 4
  460. a5 3
  461.  * inet.c
  462.  *
  463.  * @@(#)inet.c 1.7 88/02/08 Copyr 1986 Sun Micro
  464. d13 13
  465. a25 10
  466. #include "../dev/saio.h"
  467. #include "../h/socket.h"
  468. #include "../dev/if.h"
  469. #include "../h/in.h"
  470. #include "../dev/if_ether.h"
  471. #include "../h/in_systm.h"
  472. #include "../h/ip.h"
  473. #include "../h/sainet.h"
  474. #include "../h/sunromvec.h"
  475. #include "../h/idprom.h"
  476. d40 2
  477. a41 2
  478. #define WAITCNT    2                /* 4 sec. wait for arp/revarp */
  479.  
  480. d43 1
  481. a43 6
  482.  * Description: Fetches our Ethernet address from the ID prom
  483.  *
  484.  * Synopsis:    status = myetheraddr(ea)
  485.  *        status    :(null)
  486.  *        ea    :(char *) pointer to ethernet address structure
  487.  * Routines:    idprom, printf 
  488. d56 1
  489. a56 1
  490.  
  491. d58 4
  492. a61 13
  493.  * Description: Initialize IP state
  494.  *
  495.  *         Find out our Ethernet address and call Reverse ARP.
  496.  *         To find out our Internet address,
  497.  *         set the ARP cache to the broadcast host
  498.  *
  499.  * Synopsis:    status = inet_init(sip, sain, tmpbuf)
  500.  *        status    :(null)
  501.  *        sip    :(char *) pointer to saioreq structure
  502.  *        sain    :(char *) pointer to sainet  structure
  503.  *        tmpbuf    :(char *) pointer to temporary buffer space
  504.  *
  505.  * Routines:    myetheraddr, revarp
  506. d68 3
  507. a70 3
  508.     myetheraddr(&sain->sain_myether);    /* ethernet addr from IDPROM */
  509.     sain->sain_hisaddr.s_addr = 0;        /* clear address */
  510.                         /* broadcast msg. */
  511. d72 1
  512. a72 1
  513.     revarp(sip, sain, tmpbuf);        /* deter. internet address */
  514. d74 2
  515. a75 1
  516.  
  517. d77 2
  518. a78 14
  519.  * Description: Output an IP packet
  520.  *
  521.  *         Cause ARP to be invoked if necessary
  522.  *
  523.  * Synopsis:    status = ip_output(sip, buf, len, sain, tmpbuf)
  524.  *        status    :(null)
  525.  *        sip    :(char *) pointer to saioreq structure
  526.  *        buf    :(char *) address pointer to buffer
  527.  *        len    :(short)  length of IP packet
  528.  *        sain    :(char *) pointer to sainet  structure
  529.  *        tmpbuf    :(char *) pointer to temporary buffer space
  530.  *
  531.  * Routines:    arp, ipcksum, sif_xmit
  532.  *
  533. a88 1
  534.                         /* construct header */
  535. a89 2
  536.                         /* check destination addr */
  537.  
  538. d91 7
  539. a97 3
  540.     if (ip->ip_dst.s_addr != sain->sain_hisaddr.s_addr) {
  541.         sain->sain_hisaddr.s_addr = ip->ip_dst.s_addr;
  542.         arp(sip, sain, tmpbuf);
  543. d99 1
  544. a99 1
  545.     eh->ether_type = ETHERPUP_IPTYPE;
  546. d102 1
  547. a102 1
  548.                         /* checksum the packet */
  549. d105 1
  550. a105 3
  551.  
  552.                         /* set length of packet */
  553.     if (len < ETHERMIN+sizeof(struct ether_header))
  554. d107 1
  555. a107 3
  556.  
  557.                         /* transmit */
  558.  
  559. d110 1
  560. a110 1
  561.  
  562. d112 4
  563. a115 11
  564.  * Description: Check incoming packets for IP packets addressed to us.
  565.  *
  566.  *        Also, respond to ARP packets that wish to know about us.
  567.  *         Returns a length for any IP packet addressed to us, 0 otherwise.
  568.  *
  569.  * Synopsis:    status = ip_input(sip, buf, sain)
  570.  *        sip    :(char *) pointer to saioreq structure
  571.  *        sain    :(char *) pointer to sainet  structure
  572.  *        buf    :(char *) address pointer to buffer space for packet
  573.  *
  574.  * Routine:    sif_poll, sif_xmit
  575. a125 1
  576.                         /* read packet */
  577. a127 2
  578.  
  579.                         /* check header */
  580. d129 1
  581. a129 3
  582.                         /* IP packet */
  583.  
  584.     if (eh->ether_type == ETHERPUP_IPTYPE &&
  585. d132 15
  586. a146 4
  587.  
  588.                         /* make sure it's for me */
  589.  
  590.         if (ip->ip_dst.s_addr != sain->sain_myaddr.s_addr) 
  591. d150 2
  592. a151 4
  593.                         /* ARP packet */
  594.  
  595.     if (eh->ether_type == ETHERPUP_ARPTYPE &&
  596.         len >= sizeof(struct ether_header)+sizeof(struct ether_arp)) {
  597. d153 1
  598. a153 1
  599.         if (ea->arp_pro != ETHERPUP_IPTYPE) 
  600. d155 4
  601. a158 5
  602.         if (arp_spa(ea).s_addr == sain->sain_hisaddr.s_addr)
  603.             sain->sain_hisether = arp_sha(ea);
  604.  
  605.                         /* send ARP reply */
  606.  
  607. d160 3
  608. a162 1
  609.             arp_tpa(ea).s_addr == sain->sain_myaddr.s_addr) {
  610. d164 1
  611. a164 1
  612.             eh->ether_dhost = arp_sha(ea);
  613. d166 8
  614. a173 4
  615.             arp_tha(ea) = arp_sha(ea);
  616.             arp_tpa(ea) = arp_spa(ea);
  617.             arp_sha(ea) = sain->sain_myether;
  618.             arp_spa(ea) = sain->sain_myaddr;
  619. d181 1
  620. a181 1
  621.  
  622. d183 3
  623. a185 10
  624.  * Description: ARP, Broadcasts to determine Ethernet address given IP address
  625.  *         See RFC 826
  626.  *
  627.  * Synopsis:    status = arp(sip, sain, tmpbuf)
  628.  *        status    :(null)
  629.  *        sip    :(char *) pointer to saioreq structure
  630.  *        sain    :(char *) pointer to sainet  structure
  631.  *        tmpbuf    :(char *) pointer to temporary buffer space
  632.  *
  633.  * Routines:    comarp, in_lnaof 
  634. d193 6
  635. a198 4
  636.                         /* deter. destination, lnaof
  637.                          * gets host portion of addr */ 
  638.     if (in_lnaof(sain->sain_hisaddr) == INADDR_ANY ||
  639.        (in_lnaof(sain->sain_hisaddr) & INADDR1_ANY) == INADDR1_ANY) {
  640. d202 1
  641. a202 2
  642.                         /* set up ARP packet */
  643.     out.arp_eh.ether_type = ETHERPUP_ARPTYPE;
  644. d204 11
  645. a214 17
  646.     arp_tha(&out.arp_ea) = etherbroadcastaddr;    /* what we want */
  647.     arp_tpa(&out.arp_ea).s_addr = sain->sain_hisaddr.s_addr;
  648.  
  649.     comarp(sip, sain, &out, tmpbuf);    /* transmit */
  650. }
  651.  
  652. /*
  653.  * Description: Reverse ARP client side
  654.  *         Determine our Internet address given our Ethernet address
  655.  *         See RFC 903
  656.  *
  657.  * Synopsis:    status = revarp(sip, sain, tmpbuf)
  658.  *        status    :(null)
  659.  *        sip    :(char *) pointer to saioreq structure
  660.  *        sain    :(char *) pointer to sainet  structure
  661.  *        tmpbuf    :(char *) pointer to temporary buffer space
  662.  *
  663. a221 1
  664.                         /* set up ARP packet */
  665. d223 6
  666. a228 1
  667.     out.arp_eh.ether_type = ETHERPUP_REVARPTYPE;
  668. d230 11
  669. a240 19
  670.     arp_tha(&out.arp_ea) = sain->sain_myether;
  671.     arp_tpa(&out.arp_ea).s_addr = 0;    /* what we want to find out */
  672.  
  673.     comarp(sip, sain, &out, tmpbuf);    /* transmit */
  674. }
  675.  
  676. /*
  677.  * Description: Common ARP code 
  678.  *         Broadcast the packet and wait for the right response.
  679.  *         Fills in *sain with the results
  680.  *
  681.  * Synopsis:    status = comarp(sip, sain, out, tmpbuf)
  682.  *        status    :(null)
  683.  *        sip    :(char *) pointer to saioreq structure
  684.  *        sain    :(char *) pointer to sainet  structure
  685.  *        out    :(char *) pointer to ARP packet
  686.  *        tmpbuf    :(char *) pointer to temporary buffer space
  687.  *
  688.  * Routines:    bcmp, ether_print, inet_print, sif_xmit,
  689. d249 3
  690. a251 3
  691.     register int e, count, time, feedback, len, delay = 2;
  692.     char    *ind = "-\\|/";
  693.                         /* fill the header */
  694. d255 2
  695. a256 2
  696.     out->arp_ea.arp_hrd = ARPHRD_ETHER;
  697.     out->arp_ea.arp_pro = ETHERPUP_IPTYPE;
  698. d259 4
  699. a262 2
  700.     arp_sha(&out->arp_ea) = sain->sain_myether;
  701.     arp_spa(&out->arp_ea).s_addr = sain->sain_myaddr.s_addr;
  702. a265 1
  703.                         /* timeout message */
  704. d268 4
  705. a271 2
  706.                 printf("Requesting Ethernet address for ");
  707.                 inet_print(arp_tpa(&out->arp_ea));
  708. d273 2
  709. a274 2
  710.                 printf("Requesting Internet address for ");
  711.                 ether_print(&arp_tha(&out->arp_ea));
  712. a276 2
  713.                         /* transmit */
  714.  
  715. d279 4
  716. a282 8
  717.         
  718. #ifdef SUN3F                          
  719.                 /* Sun-3/F runs at 20 MHZ */
  720.                 time = millitime() + (delay * 800);     /* broadcast delay */
  721. #else
  722.                 time = millitime() + (delay * 1000);    /* broadcast delay */
  723. #endif SUN3F
  724.         printf("%c\b", ind[feedback++ % 4]);    /* Show activity */
  725. d284 1
  726. a284 1
  727.                         /* poll for reply */
  728. a286 2
  729.  
  730.                         /* check length */
  731. d289 1
  732. a289 2
  733.                         /* IP packet, waiting for ARP */
  734.             if (in->arp_ea.arp_pro != ETHERPUP_IPTYPE)
  735. a290 1
  736.                         /* ARP packet */
  737. d292 1
  738. a292 1
  739.                 if (in->arp_eh.ether_type != ETHERPUP_ARPTYPE)
  740. d296 3
  741. a298 2
  742.                 if (arp_spa(&in->arp_ea).s_addr !=
  743.                     arp_tpa(&out->arp_ea).s_addr)
  744. a299 3
  745.  
  746.                         /* timeout message */
  747.  
  748. d302 1
  749. a302 1
  750.                     ether_print(&arp_sha(&in->arp_ea));
  751. d304 1
  752. a304 1
  753.                 sain->sain_hisether = arp_sha(&in->arp_ea);
  754. d307 1
  755. a307 2
  756.  
  757.                 if (in->arp_eh.ether_type !=ETHERPUP_REVARPTYPE)
  758. d311 3
  759. a313 3
  760.                 if (bcmp((caddr_t)&arp_tha(&in->arp_ea),
  761.                          (caddr_t)&arp_tha(&out->arp_ea), 
  762.                          sizeof (struct ether_addr)) != 0)
  763. a314 5
  764.                         /* print IP address */
  765.                 printf("Using IP Address ");
  766.                 inet_print(arp_tpa(&in->arp_ea));
  767.  
  768.                         /* short circuit first ARP */
  769. d316 16
  770. a331 3
  771.                 sain->sain_myaddr   = arp_tpa(&in->arp_ea);
  772.                 sain->sain_hisaddr  = arp_spa(&in->arp_ea);
  773.                 sain->sain_hisether = arp_sha(&in->arp_ea);
  774. a334 1
  775.         delay = delay * 2;        /* Double the request delay */
  776. d336 2
  777. a337 1
  778.         if (delay > 64)            /* max. delay is 64 seconds */
  779. d339 1
  780. a339 1
  781.                         /* reset ethernet */
  782. d344 1
  783. a344 1
  784.  
  785. d346 1
  786. a346 7
  787.  * Description: Return the host portion of an internet address.
  788.  *
  789.  * Synopsis:    status = in_lnaof(in)
  790.  *        status    :       host addr
  791.  *        in    :(in_addr) pointer to internet address
  792.  *
  793.  * Routines:    ntohl
  794. d360 23
  795. a382 1
  796.  
  797. d384 2
  798. a385 6
  799.  * Description: Compute one's complement checksum for IP packet headers 
  800.  *
  801.  * Synopsis:    status = ipcksum(cp, count)
  802.  *        status    :      checksum
  803.  *        cp    :(char *) pointer to IP packet
  804.  *        count    :(u_short) length of IP packet
  805. d405 1
  806. a405 8
  807.  
  808. /*
  809.  * Description: Prints the internet address
  810.  *
  811.  * Synopsis:    status = inet_print(s)
  812.  *        status    :(null)
  813.  *        s    :(char *) pointer to internet address
  814.  */
  815. d409 6
  816. a414 4
  817.     int    len = 2;
  818.  
  819.     printf("%d.%d.%d.%d = ", s.S_un.S_un_b.s_b1, s.S_un.S_un_b.s_b2,
  820.         s.S_un.S_un_b.s_b3, s.S_un.S_un_b.s_b4);
  821. a415 14
  822.     printhex(s.S_un.S_un_b.s_b1, len);
  823.     printhex(s.S_un.S_un_b.s_b2, len);
  824.     printhex(s.S_un.S_un_b.s_b3, len);
  825.     printhex(s.S_un.S_un_b.s_b4, len);
  826.     printf("\n");
  827. }
  828.  
  829. /*
  830.  * Description: Prints the ethernet address
  831.  *
  832.  * Synopsis:    status = ether_print(s)
  833.  *        status    :(null)
  834.  *        s    :(char *) pointer to ethernet address
  835.  */
  836. @
  837.